using System;
using System.Collections;
using System.Data;
using FirebirdSql.Data.FirebirdClient;


namespace Prologis.ShifterNT {

    public class ParameterCache {


       
        ParameterCache() { }
        static Hashtable paramCache = Hashtable.Synchronized(new Hashtable());


       
        private static IDataParameter[] DiscoverSpParameterSet(string spName, string cs, bool includeReturnValueParameter) {

            using (FbConnection cn = new FbConnection(cs))
            

            using (FbCommand cmd = new FbCommand(spName, cn)) {

                cn.Open();
                cmd.CommandType = CommandType.StoredProcedure;

                FbCommandBuilder.DeriveParameters(cmd);

                if (!includeReturnValueParameter) {
                    cmd.Parameters.RemoveAt(0);
                }

                IDataParameter[] discoveredParameters = new FbParameter[cmd.Parameters.Count];

                for (int i = 0; i < discoveredParameters.Length; i++) {
                    
                    /*
                    string name = cmd.Parameters[i].ParameterName;
                    if (name[0] == '@') {
                        cmd.Parameters[i].ParameterName = name.Substring(1);
                    }
                     */ 

                    discoveredParameters[i] = cmd.Parameters[i];
                }

                //cmd.Parameters.CopyTo(discoveredParameters, 0);

                return discoveredParameters;
            }
        }



    
        private static IDataParameter[] CloneParameters(IDataParameter[] originalParameters) {
            //deep copy of cached OracleParameter array
            IDataParameter[] clonedParameters = new FbParameter[originalParameters.Length];

            for (int i = 0, j = originalParameters.Length; i < j; i++) {
                clonedParameters[i] = (IDataParameter)((ICloneable)originalParameters[i]).Clone();
            }

            return clonedParameters;
        }


      
        public static void CacheParameterSet(string commandText, string cs, params IDataParameter[] commandParameters) {
            string hashKey = cs + ":" + commandText;
            paramCache[hashKey] = commandParameters;
        }


        public static IDataParameter[] GetCachedParameterSet(string commandText, string cs) {
            string hashKey = cs + ":" + commandText;

            IDataParameter[] cachedParameters = (IDataParameter[])paramCache[hashKey];

            if (cachedParameters == null) {
                return null;
            }
            else {
                return CloneParameters(cachedParameters);
            }
        }

      
      
        public static IDataParameter[] GetSpParameterSet(string spName, string cs) {
            return GetSpParameterSet(spName, cs, false);
        }

      
     
        public static IDataParameter[] GetSpParameterSet(string spName, string cs, bool includeReturnValueParameter) {
            string hashKey = cs + ":" + spName + (includeReturnValueParameter ? ":include ReturnValue Parameter" : String.Empty);

            IDataParameter[] cachedParameters;

            cachedParameters = (IDataParameter[])paramCache[hashKey];

            if (cachedParameters == null) {
                cachedParameters = (IDataParameter[])(paramCache[hashKey] = DiscoverSpParameterSet(spName, cs, includeReturnValueParameter));
            }

            return CloneParameters(cachedParameters);
        }
    }

}
